import { FastifyInstance } from "fastify";
import { Static, Type } from "@sinclair/typebox";
import { Op } from "sequelize";
import { Organization, Vacancy } from "@db";
import { config } from "@config";

const vacancyQuery = Type.Object({
    query: Type.Optional(Type.String()),
    page: Type.Optional(Type.Number({ default: 0 })),
    sort: Type.Optional(Type.String()),
    professionalRole: Type.Optional(Type.String()),
    qualification: Type.Optional(Type.String()),
    isPartTime: Type.Optional(Type.Boolean()),
    isRemote: Type.Optional(Type.Boolean()),
    salaryFrom: Type.Optional(Type.Number()),
});

const vacancyParams = Type.Object({
    vacancyId: Type.Number(),
});

const sorts = {
    date: ["createdAt", "DESC"],
    salaryDESC: ["salary.to", "DESC"],
    salaryASC: ["salary.from", "ASC"],
};

export const vacancy = async (fastify: FastifyInstance) => {
    fastify.get<{
        Params: Static<typeof vacancyParams>;
    }>(
        "/student/vacancy/:vacancyId",
        {
            schema: {
                tags: ["student"],
                params: vacancyParams,
            },
        },
        async (req, res) => {
            const vacancy = await Vacancy.findByPk(req.params.vacancyId);
            return res.send({
                ...vacancy.dataValues,
                organization: await Organization.findOne({
                    where: {
                        id: vacancy.organizationId,
                    },
                    attributes: ["name", "photo"],
                }).then(({ id, name, photo, isVerified }) => {
                    return {
                        id,
                        name,
                        photo: photo
                            ? "https://" +
                              config.host +
                              "/files/organizationAvatars/" +
                              photo
                            : null,
                        isVerified,
                    };
                }),
                organizationId: undefined,
            });
        }
    );

    fastify.get<{ Querystring: Static<typeof vacancyQuery> }>(
        "/student/vacancy",
        {
            preHandler: fastify.auth("student"),
            schema: {
                tags: ["student"],
                querystring: vacancyQuery,
            },
        },
        async (req, res) => {
            const {
                page,
                sort,
                professionalRole,
                qualification,
                isPartTime,
                isRemote,
                salaryFrom,
                query,
            } = req.query;

            //спидкод не круто некрасиво ну и ладно
            const where: any = {};

            if (query)
                where.title = {
                    [Op.iLike]: `%${query}%`,
                };
            if (professionalRole) where.professionalRole = professionalRole;

            if (qualification) where.qualification = qualification;

            if ("isPartTime" in req.query) where.isPartTime = isPartTime;

            if ("isRemote" in req.query) where.isRemote = isRemote;

            if (salaryFrom)
                where["salary.from"] = {
                    [Op.gte]: salaryFrom,
                };

            const vacancies = await Vacancy.findAll({
                where,
                offset: page * 50,
                limit: 50,
                //сортировка или дефолт по дате
                order: [sorts[sort] || [sorts.date]],
                attributes: [
                    "id",
                    "title",
                    "salary",
                    "isRemote",
                    "isPartTime",
                    "address",
                    "skills",
                    "professionalRole",
                    "qualification",
                    "createdAt",
                    "organizationId",
                ],
            });

            return res.send(
                await Promise.all(
                    vacancies.map(async (vacancy) => {
                        return {
                            ...vacancy.dataValues,
                            organization: await Organization.findOne({
                                where: {
                                    id: vacancy.organizationId,
                                },
                                attributes: ["name", "photo"],
                            }).then(({ id, name, photo, isVerified }) => {
                                return {
                                    id,
                                    name,
                                    photo: photo
                                        ? "https://" +
                                          config.host +
                                          "/files/organizationAvatars/" +
                                          photo
                                        : null,
                                    isVerified,
                                };
                            }),
                            organizationId: undefined,
                        };
                    })
                )
            );
        }
    );
};
